package com.cheer.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.cheer.entity.OaUserEntity;
import com.cheer.enums.OaIntegralRuleEnum;
import com.cheer.exception.ServiceException;
import com.cheer.service.*;
import com.cheer.vo.OaTaskInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
public class CacheServiceImpl implements CacheService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private TaskService taskService;

    @Autowired
    private AuthService authService;

    @Autowired
    private HttpSession httpSession;

    @Autowired
    private SystemConfigService systemConfigService;

    /**
     * 用户抽奖的key
     */
    private final static String LOTTERY_USER_EXCHANGE_KEY = "lottery:userid:{}:date:{}";

    /**
     * 用户的任务是否全部完成
     */
    private final static String LOTTERY_USER_TASK_KEY = "lottery:userid:{}:date:{}:task";

    /**
     * 首页增加
     */
    private final static String HOME_USER_TASK_KEY = "home:openid:{}:date:{}:task";

    /**
     * 用户任务
     */
    private final static String TASK_USER_KEY = "task:openid:{}:date:{}:task:{}";



    @Override
    public void addUserExchangeTime(OaUserEntity oaUser) {
        Integer exchangeTime = getExchangeTime(oaUser);
        exchangeTime = exchangeTime + 1;
        // 写回到缓存中
        String key = getExchangeKey(oaUser);
        stringRedisTemplate.opsForValue().set(key, String.valueOf(exchangeTime), 1L, TimeUnit.DAYS );
    }

    @Override
    public void decUserExchangeTime(OaUserEntity oaUser) {
        Integer exchangeTime = getExchangeTime(oaUser);
        if(exchangeTime <= 0){
            throw new ServiceException("今日抽奖次数已用完！");
        }
        exchangeTime = exchangeTime - 1;
        // 写回到缓存中
        String key = getExchangeKey(oaUser);
        stringRedisTemplate.opsForValue().set(key, String.valueOf(exchangeTime), 1L, TimeUnit.DAYS );
    }


    /**
     * 获取当前剩余抽奖次数
     * @param oaUser
     */
    @Override
    public Integer getExchangeTime(OaUserEntity oaUser) {
        String key = getExchangeKey(oaUser);
        String time = stringRedisTemplate.opsForValue().get(key);
        Integer exchangeTime;
        if(time == null){
            // 默认给予次数
            exchangeTime = Integer.valueOf(systemConfigService
                    .getConfigValueByKey(SystemConfigServiceImpl.INT_DEFAULT_TIME));
        }else{
            exchangeTime = Integer.valueOf(time);
        }
        // 是否增加了当前任务完成的标识
        String taskKey = StrUtil.format(LOTTERY_USER_TASK_KEY, oaUser.getId(),
                DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN));

        if(StrUtil.isBlank(stringRedisTemplate.opsForValue().get(taskKey))){
            OaTaskInfoVO oaTaskInfoVO = taskService.task(oaUser.getOpenid(), authService.getExUserByOpenId(httpSession));
            if(oaTaskInfoVO.allTaskIsFinished()){
                Integer taskTime = Integer.valueOf(systemConfigService.getConfigValueByKey(SystemConfigServiceImpl.INT_TASK_TIME));
                exchangeTime += taskTime;
                stringRedisTemplate.opsForValue().set(taskKey, "allTaskIsFinished", 1, TimeUnit.DAYS);
            }
        }
        stringRedisTemplate.opsForValue().set(key, String.valueOf(exchangeTime), 1, TimeUnit.DAYS);
        return exchangeTime;
    }

    private String getExchangeKey(OaUserEntity oaUser){

        String date = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);
        return StrUtil.format(LOTTERY_USER_EXCHANGE_KEY, oaUser.getId(), date);
    }

    private String getTaskUserKey(String openId, OaIntegralRuleEnum oaIntegralRule){
        String date = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);
        return StrUtil.format(TASK_USER_KEY, openId, date, oaIntegralRule.name());
    }

    @Override
    public Boolean taskIsFinished(String openId, OaIntegralRuleEnum oaIntegralRule){
        String taskUserKey = getTaskUserKey(openId, oaIntegralRule);
        return StrUtil.isNotBlank(stringRedisTemplate.opsForValue().get(taskUserKey));
    }

    @Override
    public void setTaskUserValue(String openId, OaIntegralRuleEnum oaIntegralRule){
        if(taskIsFinished( openId,  oaIntegralRule)  == false){
            String taskUserKey = getTaskUserKey(openId, oaIntegralRule);
            stringRedisTemplate.opsForValue().set(taskUserKey, "finished", 1, TimeUnit.DAYS);
        }
    }


    private String getHomeTaskKey(String openid){
        String date = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);
        return StrUtil.format(HOME_USER_TASK_KEY, openid, date);
    }


    @Override
    public void setHomeTaskFlag(String openid, String flag) {
        String taskUserKey = getHomeTaskKey(openid);
        stringRedisTemplate.opsForValue().set(taskUserKey, "finished", 1, TimeUnit.DAYS);
    }

    @Override
    public String getHomeTaskFlag(String openid) {
        return null;
    }


}
